<template>
  <div class="pod-management-container">
    <el-card shadow="never" class="main-card">
      <!-- 顶部配置选择栏 -->
      <div class="config-selector">
        <el-form :inline="true" class="filter-form">
          <el-form-item label="CICD配置" class="filter-item">
            <el-select
              v-model="selectedConfig"
              placeholder="请选择CICD配置"
              class="config-select"
              filterable
              clearable
              @change="handleConfigChange"
            >
              <el-option
                v-for="config in configOptions.filter((c) => c.id != null)"
                :key="config.id"
                :label="
                  config.k8sApiServer
                    ? `镜像部署：${config.k8sApiServer}`
                    : `本地部署：${config.host}`
                "
                :value="Number(config.id)"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>

      <!-- 内容区切换：本地部署用表格，镜像部署用卡片，带淡入淡出过渡 -->
      <transition name="fade" mode="out-in">
        <template v-if="loading">
          <el-skeleton :rows="4" animated style="margin: 24px 0" />
        </template>
        <template v-else-if="isLocalDeploy">
          <el-table :data="pods || []" style="width: 100%">
            <el-table-column prop="name" label="服务名称" min-width="120" />
            <el-table-column prop="port" label="端口" min-width="80" />
            <el-table-column prop="pid" label="PID" min-width="80" />
            <el-table-column prop="type" label="类型" min-width="80" />
            <el-table-column label="操作" min-width="200">
              <template #default="{ row }">
                <template v-if="row.status === 'WAITING' || row.status === 'FAIL'">
                  <el-button size="small" type="success" @click.stop="startService(row)">
                    启动
                  </el-button>
                </template>
                <template v-if="row.status === 'RUNNING'">
                  <el-button size="small" type="danger" @click.stop="stopService(row)">
                    停止
                  </el-button>
                </template>
                <el-button size="small" @click.stop="handleConfigFileCommand(row)">
                  配置文件
                </el-button>
                <el-button size="small" @click.stop="showDetails(row)">详情</el-button>
                <el-button size="small" @click.stop="showLogs(row)">日志</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
        <template v-else>
          <div class="pod-cards-wrapper">
            <div class="pod-cards-container">
              <div
                v-for="pod in visiblePods"
                :key="pod.uid"
                class="pod-card"
                @click="handlePodClick(pod)"
              >
                <div class="card-header">
                  <div class="pod-name">
                    <el-tooltip :content="pod.podName" placement="top">
                      <span>{{ pod.podName }}</span>
                    </el-tooltip>
                  </div>
                  <el-tag
                    :type="getStatusTagType(pod.status)"
                    size="small"
                    effect="dark"
                    class="status-tag"
                  >
                    {{ getStatusLabel(pod.status) }}
                  </el-tag>
                </div>
                <div class="card-body">
                  <div class="info-row">
                    <span class="info-label">命名空间:</span>
                    <span class="info-value">{{ pod.namespace }}</span>
                  </div>
                  <div class="info-row">
                    <span class="info-label">容器名称:</span>
                    <span class="info-value">{{ pod.containerName || "N/A" }}</span>
                  </div>
                  <div class="info-row">
                    <span class="info-label">镜像:</span>
                    <el-tooltip :content="pod.image" placement="top">
                      <span class="info-value image-value">{{ pod.image }}</span>
                    </el-tooltip>
                  </div>
                  <div class="info-row">
                    <span class="info-label">Pod IP:</span>
                    <span class="info-value">{{ pod.podIp || "N/A" }}</span>
                  </div>
                  <div class="info-row">
                    <span class="info-label">启动时间:</span>
                    <span class="info-value">{{ formatDate(pod.startTime) }}</span>
                  </div>
                </div>
                <div class="card-footer">
                  <el-button
                    size="small"
                    :icon="Document"
                    class="log-btn"
                    @click.stop="showLogs(pod)"
                  >
                    查看日志
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </template>
      </transition>

      <!-- 优化后的日志查看对话框 -->
      <el-dialog
        v-model="logDialogVisible"
        title="服务日志"
        width="80%"
        @close="handleLogDialogClose"
      >
        <div class="log-toolbar">
          <div>
            <el-button-group>
              <el-button
                type="primary"
                :icon="Refresh"
                :loading="logLoading"
                size="small"
                @click="reconnectLogs"
              >
                刷新
              </el-button>
              <el-button
                type="success"
                :disabled="currentPodLogs.length === 0"
                size="small"
                @click="downloadLogs"
              >
                下载
              </el-button>
              <el-button
                type="info"
                :disabled="currentPodLogs.length === 0"
                size="small"
                @click="copyLogs"
              >
                复制
              </el-button>
            </el-button-group>
            <el-tag class="log-status" size="small">{{ connectionStatus.text }}</el-tag>
          </div>
          <div>
            <el-switch
              v-model="autoScroll"
              active-text="自动滚动"
              inactive-text="手动滚动"
              size="small"
              style="margin-right: 10px"
            />
            <el-input
              v-model="logSearchText"
              placeholder="搜索日志内容"
              clearable
              size="small"
              style="width: 200px"
              @keyup.enter="highlightSearch"
            >
              <template #append>
                <el-button :icon="Search" @click="highlightSearch" />
              </template>
            </el-input>
          </div>
        </div>
        <el-scrollbar
          ref="logScrollbar"
          v-loading="logLoading"
          class="log-content"
          :class="{ 'search-active': logSearchText }"
        >
          <div v-if="currentPodLogs.length > 0" class="log-lines-container">
            <div
              v-for="(logLine, index) in currentPodLogs"
              :key="index"
              class="log-line"
              :class="{
                'error-line': hasLogLevel(logLine, 'error'),
                'warn-line': hasLogLevel(logLine, 'warn'),
                'info-line': hasLogLevel(logLine, 'info'),
                'debug-line': hasLogLevel(logLine, 'debug'),
                'highlight-line': isLineHighlighted(logLine),
              }"
            >
              <span class="line-number">{{ index + 1 }}</span>
              <span v-if="showTimestamp" class="timestamp">
                {{ extractTimestamp(logLine) || "--" }}
              </span>
              <span class="line-content">
                <template v-if="parseNginxLogLine(logLine)">
                  <span class="log-ip">{{ parseNginxLogLine(logLine)?.ip }}</span>
                  <span>- -</span>
                  <span class="log-time">[{{ parseNginxLogLine(logLine)?.time }}]</span>
                  <span></span>
                  <span
                    class="log-method"
                    :class="`m-${parseNginxLogLine(logLine)?.method.toLowerCase()}`"
                  >
                    {{ parseNginxLogLine(logLine)?.method }}
                  </span>
                  <span></span>
                  <span class="log-path">{{ parseNginxLogLine(logLine)?.path }}</span>
                  <span></span>
                  <span class="log-proto">{{ parseNginxLogLine(logLine)?.proto }}</span>
                  <span></span>
                  <span class="log-status" :class="`s-${parseNginxLogLine(logLine)?.status}`">
                    {{ parseNginxLogLine(logLine)?.status }}
                  </span>
                  <span></span>
                  <span class="log-size">{{ parseNginxLogLine(logLine)?.size }}</span>
                  <span></span>
                  <span class="log-ua">
                    <el-tooltip :content="parseNginxLogLine(logLine)?.ua" placement="top">
                      <span>{{ parseNginxLogLine(logLine)?.ua.slice(0, 20) }}...</span>
                    </el-tooltip>
                  </span>
                </template>
                <template v-else>
                  {{ logLine }}
                </template>
              </span>
            </div>
          </div>
          <el-empty v-else description="暂无日志数据" />
        </el-scrollbar>
        <div class="log-footer">
          <el-tag size="small" type="info">共 {{ currentPodLogs.length }} 行</el-tag>
          <el-tag v-if="matchedLines > 0" size="small" type="success">
            匹配 {{ matchedLines }} 行
          </el-tag>
        </div>
      </el-dialog>

      <!-- Pod 详情对话框（骨架） -->
      <el-dialog v-model="detailDialogVisible" title="Pod 详情" width="70%">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="名称">
            {{ detailPod?.podName || detailPod?.name }}
          </el-descriptions-item>
          <el-descriptions-item label="命名空间">{{ detailPod?.namespace }}</el-descriptions-item>
          <el-descriptions-item label="容器">{{ detailPod?.containerName }}</el-descriptions-item>
          <el-descriptions-item label="镜像">{{ detailPod?.image }}</el-descriptions-item>
          <el-descriptions-item label="Pod IP">{{ detailPod?.podIp }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag :type="getStatusTagType(detailPod?.status || '')">
              {{ getStatusLabel(detailPod?.status || "") }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="启动时间">
            {{ formatDate(detailPod?.startTime as any) }}
          </el-descriptions-item>
          <el-descriptions-item label="重启次数">
            {{ (detailPod as any)?.restartCount }}
          </el-descriptions-item>
        </el-descriptions>

        <div style="margin-top: 16px">
          <ECharts :options="cpuOptions" height="220px" />
        </div>
        <div style="margin-top: 12px">
          <ECharts :options="memOptions" height="220px" />
        </div>
        <template #footer>
          <el-button @click="detailDialogVisible = false">关闭</el-button>
        </template>
      </el-dialog>

      <!-- 操作确认弹框 -->
      <el-dialog
        v-model="operationDialog.visible"
        :title="operationDialog.title"
        :before-close="cancelOperation"
        width="30%"
        :close-on-click-modal="!operationDialog.isExecuting"
        :close-on-press-escape="!operationDialog.isExecuting"
      >
        <div v-if="!operationDialog.isExecuting">
          <span>{{ operationDialog.message }}</span>
        </div>
        <div v-else class="operation-progress">
          <el-progress
            :percentage="operationDialog.progress"
            :status="operationDialog.progress === 100 ? 'success' : undefined"
            :stroke-width="8"
            class="progress-bar"
          />
          <div class="progress-message">
            {{ operationDialog.statusMessage }}
          </div>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button v-if="!operationDialog.isExecuting" @click="cancelOperation">
              取 消
            </el-button>
            <el-button v-if="!operationDialog.isExecuting" type="primary" @click="confirmOperation">
              确 定
            </el-button>
            <el-button v-else type="primary" disabled>执行中...</el-button>
          </span>
        </template>
      </el-dialog>

      <div v-if="loadingMore" class="loading-more">
        <el-icon class="is-loading"><Loading /></el-icon>
        加载中...
      </div>

      <div v-if="filteredPods.length === 0 && !loading" class="empty-tip">
        <el-empty :description="emptyDescription" />
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick, watch, watchEffect } from "vue";
import {
  Refresh,
  Search,
  Loading,
  Connection,
  SuccessFilled,
  CloseBold,
  QuestionFilled,
  Document,
} from "@element-plus/icons-vue";
import PodApi from "@/api/manger/pod/index";
import CIcdConfigAPI, { CicdConfigVO } from "@/api/build/cicdConfig";
import { ElMessage } from "element-plus";
// 假设本地服务API如下
import LocalAPI from "@/api/manger/local/index";
import { useRoute, useRouter } from "vue-router";
import ECharts from "@/components/ECharts/index.vue";
import { useDevopsStore } from "@/store";
import ServiceManagerAPI from "@/api/serviceManager";
const route = useRoute();
const router = useRouter();
const devopsStore = useDevopsStore();

// 定义Pod类型
interface Pod {
  podName: string;
  namespace: string;
  uid: string;
  startTime: Date;
  podIp: string;
  containerName: string;
  status: string;
  restartCount: number;
  image: string;
}

// 详情对话框状态
const detailDialogVisible = ref(false);
const detailPod = ref<Pod | any>(null);

function showDetails(row: any) {
  detailPod.value = row;
  detailDialogVisible.value = true;
}

const cpuOptions = computed(() => ({
  title: { text: "CPU 使用率", left: "left", textStyle: { fontSize: 12 } },
  tooltip: { trigger: "axis" },
  xAxis: { type: "category", data: ["10:00", "10:05", "10:10", "10:15", "10:20"] },
  yAxis: { type: "value", axisLabel: { formatter: "{value}%" } },
  series: [{ type: "line", data: [20, 45, 30, 50, 35] }],
}));
const memOptions = computed(() => ({
  title: { text: "内存使用", left: "left", textStyle: { fontSize: 12 } },
  tooltip: { trigger: "axis" },
  xAxis: { type: "category", data: ["10:00", "10:05", "10:10", "10:15", "10:20"] },
  yAxis: { type: "value", axisLabel: { formatter: (v: number) => `${v}MB` } },
  series: [{ type: "line", data: [180, 220, 210, 240, 230] }],
}));

// 响应式状态
const logDialogVisible = ref(false);
const currentPodLogs = ref<string[]>([]);
const logLoading = ref(false);
const logEventSource = ref<EventSource | null>(null);
const logBuffer = ref<string[]>([]);
const bufferTimer = ref<number | null>(null);
const autoScroll = ref(true);
const logSearchText = ref("");
const logScrollbar = ref();
const selectedConfig = ref<number | undefined>(undefined);

const configOptions = ref<CicdConfigVO[]>([]);
const pods = ref<any[]>([]);
const loading = ref(false);
const statusFilter = ref("");
const searchQuery = ref("");
const selectedPod = ref<Pod | null>(null);
const visibleCount = ref(20);
const loadingMore = ref(false);
const heartbeatTimer = ref<number>();
const showTimestamp = ref(true);
const activeLevels = ref<string[]>(["error", "warn", "info"]);

// 操作状态管理
// const operationStates = ref(new Map<string, { loading: boolean; progress: number; message: string }>());

// 操作确认弹框
const operationDialog = ref({
  visible: false,
  title: "",
  message: "",
  operation: null as (() => Promise<void>) | null,
  currentPod: null as any,
  // 进度状态
  isExecuting: false,
  progress: 0,
  statusMessage: "",
});

// 状态选项
const podStatusOptions = [
  { value: "RUNNING", label: "运行中", type: "success" },
  { value: "FAIL", label: "失败", type: "danger" },
  { value: "WAITING", label: "待发布", type: "info" },
];

function getStatusLabel(status: string) {
  const found = podStatusOptions.find((s) => s.value === status);
  return found ? found.label : status;
}
type TagType = "success" | "danger" | "info" | "warning" | "primary";
function getStatusTagType(status: string): TagType {
  if (status === "RUNNING" || status === "Running") return "success";
  if (status === "FAIL" || status === "Failed") return "danger";
  if (status === "WAITING" || status === "Pending" || status === "Waiting") return "info";
  return "info";
}

// 计算属性
const filteredPods = computed(() => {
  let result = pods.value;

  // 命名空间过滤（仅k8s模式适用）
  if (devopsStore.isK8s && devopsStore.selectedNamespace) {
    result = result.filter((pod) => pod.namespace === devopsStore.selectedNamespace);
  }

  if (statusFilter.value) {
    result = result.filter((pod) => pod.status === statusFilter.value);
  }

  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase();
    result = result.filter(
      (pod) =>
        pod.podName.toLowerCase().includes(query) ||
        pod.namespace.toLowerCase().includes(query) ||
        (pod.containerName && pod.containerName.toLowerCase().includes(query))
    );
  }

  return result;
});

const visiblePods = computed(() => {
  return filteredPods.value.slice(0, visibleCount.value);
});

const emptyDescription = computed(() => {
  if (searchQuery.value) return `没有找到包含"${searchQuery.value}"的Pod`;
  if (statusFilter.value) {
    const status = podStatusOptions.find((s) => s.value === statusFilter.value);
    return status ? `没有${status.label}状态的Pod` : "没有匹配状态的Pod";
  }
  return "当前命名空间下暂无Pod数据";
});
const connectionStatus = computed(() => {
  if (!logEventSource.value) {
    return { type: "info", text: "未连接", icon: Connection };
  }
  switch (logEventSource.value.readyState) {
    case EventSource.CONNECTING:
      return { type: "warning", text: "连接中...", icon: Loading };
    case EventSource.OPEN:
      return { type: "success", text: "实时连接中", icon: SuccessFilled };
    case EventSource.CLOSED:
      return { type: "danger", text: "连接已断开", icon: CloseBold };
    default:
      return { type: "info", text: "未知状态", icon: QuestionFilled };
  }
});

const matchedLines = computed(() => {
  if (!logSearchText.value) return 0;
  const searchText = logSearchText.value.toLowerCase();
  return currentPodLogs.value.filter((line) => line.toLowerCase().includes(searchText)).length;
});

const isLocalDeploy = computed(() => {
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);
  // 只有k8sApiServer为null或undefined时才判为本地部署
  return config && config.deployType === "local";
});

// 方法
const isLineHighlighted = (line: string) => {
  return logSearchText.value && line.toLowerCase().includes(logSearchText.value.toLowerCase());
};

const hasLogLevel = (line: string, level: string) => {
  return activeLevels.value.includes(level) && line.toLowerCase().includes(level);
};

const extractTimestamp = (line: string) => {
  const timestampRegex = /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/;
  const match = line.match(timestampRegex);
  return match ? match[0] : null;
};

// 结构化解析nginx日志
function parseNginxLogLine(line: string) {
  const regex =
    /^([\d.]+) - - \[([^\]]+)\] "(\w+) ([^ ]+) ([^ ]+)" (\d{3}) (\d+) "([^"]*)" "([^"]*)" "([^"]*)"$/;
  const m = line.match(regex);
  if (!m) return null;
  return {
    ip: m[1],
    time: m[2],
    method: m[3],
    path: m[4],
    proto: m[5],
    status: m[6],
    size: m[7],
    referer: m[8],
    ua: m[9],
    extra: m[10],
  };
}

const formatDate = (date: Date) => {
  return new Date(date).toLocaleString();
};

const handlePodClick = (pod: Pod) => {
  showLogs(pod);
};

// 修正configOptions加载后id类型
function normalizeConfigOptions(options: CicdConfigVO[]) {
  return options.filter((opt) => opt.id != null).map((opt) => ({ ...opt, id: Number(opt.id) }));
}

async function fetchConfigOptions() {
  try {
    const res = await CIcdConfigAPI.getList();
    configOptions.value = normalizeConfigOptions(res);
    // 不自动选中任何项，selectedConfig保持undefined
  } catch (error) {
    const errorMessage = (error as Error).message || "未知错误";
    ElMessage.error(`获取CICD配置失败: ${errorMessage}`);
  }
}

const reconnectLogs = () => {
  if (!selectedPod.value) return;
  closeLogDialog();
  showLogs(selectedPod.value);
};

const closeLogDialog = () => {
  if (logEventSource.value) {
    logEventSource.value.close();
    logEventSource.value = null;
  }
  if (bufferTimer.value) {
    clearTimeout(bufferTimer.value);
    bufferTimer.value = null;
  }
  logDialogVisible.value = false;
  currentPodLogs.value = [];
  logBuffer.value = [];
  logSearchText.value = "";
};

const downloadLogs = () => {
  if (!selectedPod.value || currentPodLogs.value.length === 0) return;

  const blob = new Blob([currentPodLogs.value.join("\n")], { type: "text/plain" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${selectedPod.value.podName}_${new Date().toISOString().replace(/[:.]/g, "-")}.log`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};

const copyLogs = () => {
  if (!selectedPod.value || currentPodLogs.value.length === 0) return;
  const text = currentPodLogs.value.join("\n");
  navigator.clipboard
    .writeText(text)
    .then(() => {
      ElMessage.success("日志已复制到剪贴板");
    })
    .catch(() => {
      ElMessage.error("复制失败，请手动复制");
    });
};

function handleConfigChange() {
  pods.value = [];
  // 切换配置时清空命名空间可选项
  devopsStore.setAvailableNamespaces([]);
  fetchPods();
}

const fetchPods = async () => {
  if (!selectedConfig.value) {
    pods.value = [];
    return;
  }

  loading.value = true;
  try {
    const config = configOptions.value.find((c) => c.id === selectedConfig.value);
    if (config && config.deployType === "local") {
      // 本地部署，调用本地服务接口
      pods.value = (await LocalAPI.getPodsByNamespace(config.id!)) || [];
    } else {
      // k8s部署，调用原有Pod接口
      const res = await PodApi.getPodsByNamespace(selectedConfig.value);
      pods.value = res || [];
      // 从返回的 Pod 列表中汇总命名空间
      const nsList = Array.from(
        new Set((pods.value || []).map((p: any) => p.namespace).filter(Boolean))
      );
      devopsStore.setAvailableNamespaces(nsList);
      // 若 store 中未选择命名空间且接口配置有默认值，则使用默认
      if (!devopsStore.selectedNamespace && config?.nameSpace) {
        devopsStore.setSelectedNamespace(config.nameSpace);
      }
    }
  } catch (error) {
    ElMessage.error("获取服务列表失败: " + (error as Error).message);
    pods.value = [];
  } finally {
    loading.value = false;
  }
};

const highlightSearch = () => {
  nextTick(() => {
    const container = logScrollbar.value?.$el;
    if (!container || !logSearchText.value) return;

    const text = logSearchText.value.toLowerCase();
    const lines = container.querySelectorAll(".log-line");
    let found = false;

    lines.forEach((line: Element) => {
      // 明确指定line为Element类型
      const content = line.textContent?.toLowerCase() || "";
      if (content.includes(text)) {
        line.scrollIntoView({ behavior: "smooth", block: "center" });
        found = true;
      }
    });

    if (!found) {
      ElMessage.warning("未找到匹配内容");
    }
  });
};

function showLogs(row: any) {
  logDialogVisible.value = true;
  currentPodLogs.value = [];

  // 关闭已存在的连接
  if (logEventSource.value) {
    logEventSource.value.close();
    logEventSource.value = null;
  }

  const serviceCode = row.name || row.podName;
  const baseApi = import.meta.env.VITE_APP_BASE_API || "/api";
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);

  let logUrl = "";
  if (config && config.deployType === "local") {
    // 本地部署日志接口
    logUrl = `${baseApi}/localManger/${selectedConfig.value}/${serviceCode}/logs`;
  } else {
    // 镜像部署日志接口

    logUrl = `${baseApi}/k8sManger/${selectedConfig.value}/${serviceCode}/logs`;
  }

  logEventSource.value = new EventSource(logUrl);

  // 增加对默认 message 事件的监听以进行调试
  logEventSource.value.onmessage = (event: MessageEvent) => {
    console.log("SSE 'message' event received:", event);
    if (event.data) {
      currentPodLogs.value.push(event.data);
      scrollToBottom();
    }
  };

  // 监听自定义的 log 事件
  logEventSource.value.addEventListener("log", (event: MessageEvent) => {
    console.log("SSE 'log' event received:", event);
    currentPodLogs.value.push(event.data);
    scrollToBottom();
  });

  // 错误处理
  logEventSource.value.onerror = (error) => {
    console.error("SSE connection error:", error);
    ElMessage.error("日志连接失败");
    if (logEventSource.value) {
      logEventSource.value.close();
      logEventSource.value = null;
    }
  };
}

// 关闭对话框时清理连接
function handleLogDialogClose() {
  if (logEventSource.value) {
    logEventSource.value.close();
    logEventSource.value = null;
  }
  currentPodLogs.value = [];
}

// 组件卸载时清理
onUnmounted(() => {
  if (logEventSource.value) {
    logEventSource.value.close();
    logEventSource.value = null;
  }
});

const scrollToBottom = () => {
  if (!autoScroll.value) return;
  let tryCount = 0;
  const tryScroll = () => {
    const scrollbar = logScrollbar.value;
    if (scrollbar && scrollbar.$el) {
      const wrap = scrollbar.$el.querySelector(".el-scrollbar__wrap");
      if (wrap) {
        wrap.scrollTop = wrap.scrollHeight;
      }
    }
    // 最多尝试10次，防止内容未渲染完
    if (++tryCount < 10) {
      requestAnimationFrame(tryScroll);
    }
  };
  requestAnimationFrame(tryScroll);
};

function startService(row: Pod) {
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);
  const serviceName = (row as any).name || row.podName;

  if (config?.deployType === "local") {
    operationDialog.value = {
      visible: true,
      title: "启动服务",
      message: `确定要启动服务「${serviceName}」吗？`,
      operation: () => performStartService(row),
      currentPod: row,
      isExecuting: false,
      progress: 0,
      statusMessage: "",
    };
  } else {
    ElMessage.info("当前仅支持本地部署服务的启动操作");
  }
}

function stopService(row: Pod) {
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);
  const serviceName = (row as any).name || row.podName;

  if (config?.deployType === "local") {
    operationDialog.value = {
      visible: true,
      title: "停止服务",
      message: `确定要停止服务「${serviceName}」吗？`,
      operation: () => performStopService(row),
      currentPod: row,
      isExecuting: false,
      progress: 0,
      statusMessage: "",
    };
  } else {
    ElMessage.info("当前仅支持本地部署服务的停止操作");
  }
}

// 执行启动服务
async function performStartService(row: Pod) {
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);
  const serviceName = (row as any).name || row.podName;
  const serviceId = (row as any).id as number | undefined;

  if (config?.deployType === "local") {
    const doStart = async (id: number) => {
      try {
        await ServiceManagerAPI.start(id);
        ElMessage.success(`已请求启动服务：${serviceName}`);
        fetchPods();
      } catch {
        ElMessage.error("启动失败");
      }
    };

    if (serviceId) {
      await doStart(serviceId);
    } else if (serviceName) {
      try {
        const page = await ServiceManagerAPI.getPage({
          serviceName,
          pageNum: 1,
          pageSize: 50,
        } as any);
        const list = (page?.list || []).filter(
          (i: any) => i.serviceName === serviceName && i.cicdConfigId === selectedConfig.value
        );
        if (list.length > 0 && list[0].id) {
          await doStart(list[0].id);
        } else {
          ElMessage.warning("未找到对应的服务管理记录，无法启动");
        }
      } catch {
        ElMessage.error("查询服务管理记录失败");
      }
    } else {
      ElMessage.info("缺少服务标识，无法启动");
    }
  }
}

// 执行停止服务
async function performStopService(row: Pod) {
  const config = configOptions.value.find((c) => c.id === selectedConfig.value);
  const serviceName = (row as any).name || row.podName;
  const serviceId = (row as any).id as number | undefined;

  if (config?.deployType === "local") {
    const doStop = async (id: number) => {
      try {
        await ServiceManagerAPI.stop(id);
        ElMessage.success(`已请求停止服务：${serviceName}`);
        fetchPods();
      } catch {
        ElMessage.error("停止失败");
      }
    };

    if (serviceId) {
      await doStop(serviceId);
    } else if (serviceName) {
      try {
        const page = await ServiceManagerAPI.getPage({
          serviceName,
          pageNum: 1,
          pageSize: 50,
        } as any);
        const list = (page?.list || []).filter(
          (i: any) => i.serviceName === serviceName && i.cicdConfigId === selectedConfig.value
        );
        if (list.length > 0 && list[0].id) {
          await doStop(list[0].id);
        } else {
          ElMessage.warning("未找到对应的服务管理记录，无法停止");
        }
      } catch {
        ElMessage.error("查询服务管理记录失败");
      }
    } else {
      ElMessage.info("缺少服务标识，无法停止");
    }
  }
}

// 确认操作
async function confirmOperation() {
  if (operationDialog.value.operation) {
    operationDialog.value.isExecuting = true;
    operationDialog.value.progress = 0;
    operationDialog.value.statusMessage = "正在执行操作...";

    // 模拟进度更新
    const progressInterval = setInterval(() => {
      if (operationDialog.value.progress < 90) {
        operationDialog.value.progress = Math.floor(
          operationDialog.value.progress + Math.random() * 10
        );
        operationDialog.value.statusMessage = "正在执行操作...";
      }
    }, 200);

    try {
      await operationDialog.value.operation();
      clearInterval(progressInterval);
      operationDialog.value.progress = 100;
      operationDialog.value.statusMessage = "操作完成";

      setTimeout(() => {
        operationDialog.value.visible = false;
        operationDialog.value.isExecuting = false;
      }, 1000);
    } catch {
      clearInterval(progressInterval);
      operationDialog.value.progress = 100;
      operationDialog.value.statusMessage = "操作失败";

      setTimeout(() => {
        operationDialog.value.visible = false;
        operationDialog.value.isExecuting = false;
      }, 1000);
    }
  }
}

// 取消操作
function cancelOperation() {
  if (!operationDialog.value.isExecuting) {
    operationDialog.value.visible = false;
  }
}

function handleConfigFileCommand(row: Pod) {
  const service = (row as any).name || row.podName;
  const currentConfig = configOptions.value.find((c) => c.id === selectedConfig.value);
  router.push({
    name: "ConfigFileView",
    params: { service },
    query: {
      id: selectedConfig.value,
      name: currentConfig?.host || currentConfig?.k8sApiServer || "",
      deployType: currentConfig?.deployType,
    },
  });
}

// 生命周期钩子
let lastUrlId: string | number | undefined = undefined;
watchEffect(() => {
  let id = route.query.id;
  if (Array.isArray(id)) id = id[0];
  // 只有当url参数id变化时才同步selectedConfig，避免每次configOptions变化都重置
  if (id !== lastUrlId && id && configOptions.value.length > 0) {
    selectedConfig.value = Number(id);
    lastUrlId = id;
    console.log("watchEffect: 设置selectedConfig.value=", selectedConfig.value);
  }
});

watch(selectedConfig, (val) => {
  if (val !== undefined && val !== null) {
    // 与全局上下文同步所选配置
    devopsStore.setSelectedConfigId(Number(val));
    fetchPods();
  } else {
    pods.value = [];
  }
});

onMounted(() => {
  console.log(
    "onMounted: url id=",
    route.query.id,
    "configOptions:",
    configOptions.value.map((c) => c.id)
  );
  fetchConfigOptions();
  heartbeatTimer.value = window.setInterval(() => {
    if (logEventSource.value?.readyState === EventSource.CLOSED && logDialogVisible.value) {
      ElMessage.warning("日志连接已断开，正在尝试重新连接...");
      reconnectLogs();
    }
  }, 5000);
});

onUnmounted(() => {
  if (heartbeatTimer.value) {
    clearInterval(heartbeatTimer.value);
  }
  closeLogDialog();
});

// 自动滚动到底部
watch(
  () => currentPodLogs.value.length,
  () => {
    if (autoScroll.value) {
      nextTick(() => {
        scrollToBottom();
      });
    }
  }
);
</script>
<!-- 仅替换style部分，其他代码保持不变 -->
<style scoped lang="scss">
/* 卡片底部操作按钮样式 */
.card-footer > .el-button {
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: #409eff;
  border: none;
  border-radius: 8px;
  box-shadow: none;
}
.card-footer > .el-button:hover {
  background: #337ecc;
}

/* 筛选区按钮样式 */
.config-selector .filter-form > .el-button {
  font-weight: 600;
  color: #fff;
  background: #409eff;
  border: none;
  border-radius: 8px;
  box-shadow: none;
}
.config-selector .filter-form > .el-button:hover {
  background: #337ecc;
}
.pod-management-container {
  min-height: 100vh;
  padding: 12px;
  background: #f5f7fa;
}

.config-selector,
.header-bar {
  margin-bottom: 12px;
  background: #fff;
  border: none;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.06);
  .filter-form {
    gap: 16px;
    .el-form-item {
      margin-bottom: 0;
    }
    .el-input,
    .el-select {
      color: #222;
      background: #fff;
      border: 1px solid #e6e8eb;
      border-radius: 8px;
      box-shadow: none;
    }
  }
}
.config-select {
  width: 400px;
  border-radius: 8px;
  .el-input__inner {
    color: #222;
    background: #fff;
    border: none;
    border-radius: 8px;
    box-shadow: none;
  }
}
.config-option {
  display: flex;
  align-items: center;
  padding: 2px 0;
  .config-label {
    font-size: 15px;
    font-weight: 600;
    color: #222;
  }
  .config-desc {
    margin-left: 8px;
    font-size: 12px;
    color: #888;
  }
  .el-tag {
    margin-left: 8px;
    color: #409eff;
    background: #ecf5ff;
    border: none;
    box-shadow: none;
  }
}

.pod-cards-wrapper {
  background: transparent;
}
.pod-cards-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
  padding: 12px;
  overflow-y: auto;
}
.pod-card {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  background: #fff;
  border: 1px solid #e6e8eb;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
  transition:
    box-shadow 0.2s,
    transform 0.2s,
    border-color 0.2s;
  &:hover {
    border-color: #409eff;
    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.12);
    transform: translateY(-2px);
  }
  .card-header {
    padding: 12px;
    background: #f9fafc;
    border-bottom: 1px solid #f0f2f5;
    .pod-name {
      font-size: 16px;
      font-weight: 500;
      color: #333;
    }
    .status-tag {
      margin-left: 8px;
      font-size: 13px;
      border-radius: 8px;
      &.el-tag--success {
        color: #43a047;
        background: #e8f5e9;
      }
      &.el-tag--danger {
        color: #e53935;
        background: #ffebee;
      }
      &.el-tag--warning {
        color: #fbc02d;
        background: #fff8e1;
      }
    }
  }
  .card-body {
    padding: 12px;
    font-size: 14px;
    color: #333;
    .info-row {
      margin-bottom: 6px;
      .info-label {
        width: 70px;
        color: #888;
      }
      .info-value {
        color: #222;
      }
    }
  }
  .card-footer {
    padding: 8px 12px;
    background: #f9fafc;
    border-top: 1px solid #f0f2f5;
  }
}

.log-viewer-dialog {
  .el-dialog__header {
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    background: #23272e;
    border-bottom: 1px solid #333;
    border-radius: 8px 8px 0 0;
  }
  .el-dialog__body {
    padding: 0;
    color: #e0e0e0;
    background: #181c24;
    border-radius: 0 0 8px 8px;
  }
}
.log-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  background: #23272e;
  border-bottom: 1px solid #333;
  border-radius: 8px 8px 0 0;

  .el-tag {
    margin-right: 8px;
    font-weight: 600;
    border-radius: 8px;
    box-shadow: none;
  }
  .log-status {
    margin-left: 12px;
    font-size: 13px;
    color: #80d8ff;
    background: #232946;
    border: none;
  }
}
.log-content {
  min-height: 400px;
  max-height: 60vh;
  padding: 0 0 0 8px;
  overflow-x: auto;
  overflow-y: auto;
  font-family: "Menlo", "Consolas", monospace;
  font-size: 15px;
  background: #181c24;
}
.log-lines-container {
  min-height: 100%;
}
.log-line {
  display: flex;
  align-items: flex-start;
  padding: 2px 0;
  margin-bottom: 1px;
  border-left: 4px solid transparent;
  border-radius: 3px;
  transition: background 0.15s;
  .line-number {
    flex-shrink: 0;
    width: 48px;
    margin-right: 8px;
    color: #7ec7ff;
    text-align: right;
    user-select: none;
    opacity: 0.7;
  }
  .timestamp {
    flex-shrink: 0;
    width: 130px;
    margin-right: 8px;
    font-size: 13px;
    color: #b2b2b2;
    opacity: 0.8;
  }
  .line-content {
    flex: 1;
    min-width: 0;
    color: #e0e0e0;
    word-break: break-all;
    white-space: pre-wrap;
  }
  &.error-line {
    color: #ff6b6b;
    background: #2d1a1a;
    border-left-color: #ff6b6b;
  }
  &.warn-line {
    color: #ffd166;
    background: #2d261a;
    border-left-color: #ffd166;
  }
  &.info-line {
    color: #7ec7ff;
    background: #1a2d1a;
    border-left-color: #7ec7ff;
  }
  &.debug-line {
    color: #b180d7;
    background: #1a1a2d;
    border-left-color: #b180d7;
  }
  &.highlight-line {
    color: #222;
    background: #fff59d;
  }
}
.log-footer {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 8px 16px;
  background: #23272e;
  border-top: 1px solid #333;
  .el-tag {
    font-weight: 600;
    color: #80d8ff;
    background: #232946;
    border: none;
    border-radius: 8px;
  }
}

.info-value.image-value {
  display: inline-block;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 13px;
  vertical-align: middle;
  color: #666;
  white-space: nowrap;
}

.line-content .log-ip {
  font-weight: bold;
  color: #42b983;
}
.line-content .log-time {
  color: #b2b2b2;
}
.line-content .log-method.m-get {
  font-weight: bold;
  color: #67c23a;
}
.line-content .log-method.m-post {
  font-weight: bold;
  color: #409eff;
}
.line-content .log-method.m-delete {
  font-weight: bold;
  color: #f56c6c;
}
.line-content .log-method.m-put {
  font-weight: bold;
  color: #e6a23c;
}
.line-content .log-status.s-200 {
  font-weight: bold;
  color: #67c23a;
}
.line-content .log-status.s-404 {
  font-weight: bold;
  color: #e6a23c;
}
.line-content .log-status.s-500 {
  font-weight: bold;
  color: #f56c6c;
}
.line-content .log-path {
  color: #409eff;
}
.line-content .log-ua {
  font-size: 12px;
  color: #888;
}

.operation-progress {
  text-align: center;

  .progress-bar {
    margin-bottom: 16px;

    :deep(.el-progress-bar__outer) {
      background-color: #f0f2f5;
      border-radius: 10px;
    }

    :deep(.el-progress-bar__inner) {
      border-radius: 10px;
      transition: width 0.3s ease;
    }
  }

  .progress-message {
    font-size: 14px;
    font-weight: 500;
    color: #666;
  }
}

@media (max-width: 768px) {
  .config-select {
    width: 100% !important;
  }
  .pod-cards-container {
    grid-template-columns: 1fr;
    padding: 6px;
  }
  .pod-card {
    font-size: 13px;
  }
  .log-viewer-dialog .el-dialog__body {
    padding: 0 2px;
  }
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
